SuperStrict
NoDebug

Rem  
bbdoc: MaxMod.Music
End Rem
Module MaxMod.Music
ModuleInfo "MaxMod: Music - v1.25"
ModuleInfo "Author: REDi - Cliff Harman"
ModuleInfo "License: MIT"

Import BRL.LinkedList
 
Const MM_LENGTH 			:Int = 1
Const MM_POSITION 			:Int = 2
Const MM_ISPLAYING 			:Int = 3
Const MM_FORMAT 			:Int = 4
Const MM_SAMPLERATE 		:Int = 5
Const MM_TIME	 			:Int = 6
Const MM_LOOP				:Int = 7

Const MM_MONO8				:Int = 200
Const MM_MONO16				:Int = 201
Const MM_STEREO8			:Int = 202
Const MM_STEREO16			:Int = 203



Function GetBytesPerSample:Int(Format:Int)
	Select format
		Case MM_MONO8 			; Return 1
		Case MM_MONO16			; Return 2
		Case MM_STEREO8			; Return 2
		Case MM_STEREO16		; Return 4
	EndSelect
EndFunction




Function LoadMusic:TMusic(File:Object)
	Return MaxModLoader.Load(File:Object)
EndFunction

' --------------------------------------------------------------------------------------------------



' --------------------------------------------------------------------------------------------------

'Function SampleMusic:TAudioSample(Music:TMusic)
'	Local Length:Int = Music.Geti(MM_LENGTH)
'	Local sample:TAudioSample = CreateAudioSample(length,Music.SAMPLE_RATE,SF_STEREO16LE)
'	Music.PlayStatus = 1
'	Music.FillBuffer(Int(Sample.Samples),length*4)
'	Return Sample
'EndFunction

' --------------------------------------------------------------------------------------------------

Function FreeMusic(Music:TMusic)
	If Not Music Return
	Music.Free
EndFunction
' --------------------------------------------------------------------------------------------------






Rem
bbdoc: query supported music formats for streaming.
returns: a string for use with RequestFile() ect
about:
<TABLE>
<TR><TH><B>Parameters:</B></TH><TH>Description:</TH></TR>
<TR><TD>AllSupported</TD><TD>adds an "all supported" item to the filter list</TD></TR>
<TR><TD>AllFiles</TD><TD>adds an "all files" item to the filter list</TD></TR>
<TR><TD></TD><TD></TD></TR>
</TABLE><P>
End Rem
Function MusicExtensions:String(AllSupported:Int=True,AllFiles:Int=True)
	Return MaxModLoader.GetExtensions(AllSupported,AllFiles)
EndFunction

 






Type TMusic 
    
	Field DebugData		:String				' debug messages are dumped here
	Method WriteBug(Bug$)
		DebugData:+Bug$
	EndMethod
	
	Field PlayStatus	:Int = 0			' true if music is playing else false
	Field SAMPLE_RATE 	:Int = 44100		' sample rate of the stream
	Field STREAM_FORMAT	:Int = MM_STEREO16	' the streams format
	Field STREAM_LOOP	:Int = True			' true or false
	Field STREAM_POS	:Int = 0			' current position of the stream in bytes
	Field STREAM_SIZE	:Int = 0			' total size of the stream in bytes
    
	' ---------------------------------------------------------------------------------------

	Method Free()
		GCCollect()
	EndMethod
	
	' ---------------------------------------------------------------------------------------

	Method FillBuffer(SoundData:Int,Length:Int) Abstract
	
	' ---------------------------------------------------------------------------------------

	Method Setf:Int(Param:Int,value#)
	EndMethod

	Method Getf#(Param:Int)
	EndMethod

	Method Seti:Int(Param:Int,value:Int)
		Select Param
			Case MM_LOOP			; STREAM_LOOP = value 	; Return True
			Case MM_SAMPLERATE 		; SAMPLE_RATE = value 	; Return True
			Case MM_FORMAT
				If value=MM_MONO8 Or value=MM_MONO16 Or value=MM_STEREO8 Or value=MM_STEREO16
					STREAM_FORMAT = value ; Return True
				EndIf
		EndSelect
	EndMethod
 
	Method Geti:Int(Param:Int)
		Select Param
			Case MM_ISPLAYING 		; Return PlayStatus
			Case MM_LENGTH	 		; Return STREAM_SIZE
			Case MM_POSITION 		; Return STREAM_POS
			Case MM_FORMAT	 		; Return STREAM_FORMAT
			Case MM_SAMPLERATE 		; Return SAMPLE_RATE
			Case MM_LOOP			; Return STREAM_LOOP
		EndSelect
	EndMethod

	Method GetS:String(Param:Int)
	EndMethod

EndType
  


Type MaxModLoader

	Global MMLoader:TMusic(url:Object)
	Global List:TList = CreateList()
	
	Field Name$
	Field Func:Byte Ptr
	Field Ext$

	Method New()
		List.AddLast(Self)
	EndMethod
	
	Function Create:MaxModLoader(Func:Byte Ptr,Description$,Extension$)
		Local Mod_Loader:MaxModLoader = New MaxModLoader
		Mod_Loader.Func  = Func
		Mod_Loader.Name$ = Description$
		Mod_Loader.Ext$  = Extension$
	EndFunction
	
	Function GetExtensions$(AllSupported:Int=True,AllFiles:Int=True)
		Local Txt$
		If AllSupported
			Txt$:+"All supported:"
			For Local This:MaxModLoader = EachIn List
				Txt$:+","+This.Ext.tolower()
			Next
		EndIf
		For Local This:MaxModLoader = EachIn List
			If Txt$<>"" Then Txt$:+";"
			Txt$:+This.Name$+":"+This.Ext.tolower()
		Next
		If AllFiles
			If Txt$<>"" Then Txt$:+";"
			Txt$:+"All Files:*"
		EndIf
		Return txt$
	EndFunction
	
	Function Load:TMusic(URL:Object)
		Local NewSong:TMusic
		For Local This:MaxModLoader = EachIn List
			If TStream(URL) Then TStream(URL).seek 0
			MaxModLoader.MMLoader = This.Func
			NewSong = MaxModLoader.MMLoader(URL)
			If NewSong Return NewSong
		Next
	EndFunction

EndType

